package com.rq.base.ui;

import android.text.TextUtils;

import com.rq.base.ui.impl.CtrTag;
import com.rq.base.util.LOG;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 控制器集中管理
 * watch 、 send 实现类似于 EventBus 进行 Controller 之间的数据传递
 */
public class CtrWatcher2 {

    private static CtrWatcher2 mCtrWatcher;
    private List<Object> visibleFragmentController = new ArrayList<>();
    private Object visibleActivityController = null;
    private HashMap<String, Object> watcher = new HashMap<>();

    private CtrWatcher2() {
    }

    public static CtrWatcher2 get() {
        if (mCtrWatcher == null) {
            synchronized (CtrWatcher2.class) {
                if (mCtrWatcher == null) {
                    mCtrWatcher = new CtrWatcher2();
                }
            }
        }
        return mCtrWatcher;
    }

    public void watch(String tag, Object controller) {
        if (!TextUtils.isEmpty(tag)) {
            String key = tag + controller.hashCode();
            LOG.e("CtrWatcher2", key + "<watch--->:" + controller.getClass().getSimpleName());
            watcher.put(key, controller);
        }
    }

    public void removeWatch(Object controller) {
        Method[] methods = controller.getClass().getMethods();
        for (Method method : methods) {
            Annotation[] annotations = method.getAnnotations();
            if (annotations.length > 0) {
                for (Annotation annotation : annotations) {
                    if (annotation instanceof CtrTag) {
                        CtrTag inject = (CtrTag) annotation;
                        String[] ids = inject.value();
                        for (String tag : ids) {
                            watcher.remove(tag + controller.hashCode());
                        }
                    }
                }
            }
        }
    }

    public List<Object> getAllVisibleController() {
        List<Object> all = new ArrayList<>();
        all.add(visibleActivityController);
        all.addAll(visibleFragmentController);
        return all;
    }

    public List<Object> getVisibleFragmentController() {
        return visibleFragmentController;
    }

    public Object getVisibleActivityController() {
        return visibleActivityController;
    }

    public void addActivityController(Object controller) {
        this.visibleActivityController = (Object) controller;
    }

    public void removerActivityController(Object controller) {
        this.visibleActivityController = null;
    }

    public void addFragmentController(Object controller) {
        LOG.d("CtrWatcher2", "AddFra : " + controller.getClass().getSimpleName());
        visibleFragmentController.add(controller);
        LOG.d("CtrWatcher2", "Res : " + visibleFragmentController.size());
    }

    public void removerFragmentController(Object controller) {
        visibleFragmentController.remove(controller);
    }

    public void post(String tag, Object... object) {
        for (String key : watcher.keySet()) {
            if (key.contains(tag)) {
                Object controller = watcher.get(key);
                if (controller != null) {
                    Class clazz = controller.getClass();
                    Method[] methods = clazz.getMethods();
                    for (Method method : methods) {
                        Annotation[] annotations = method.getAnnotations();
                        if (annotations.length > 0) {
                            for (Annotation annotation : annotations) {
                                if (annotation instanceof CtrTag) {
                                    for (String t : ((CtrTag) annotation).value()) {
                                        if (t != null && t.equals(tag)) {
                                            LOG.e("CtrWatcher2", tag + ".send:<" + key + ">   -->  " + method.getName());
                                            try {
                                                method.invoke(controller, tag, object);
                                            } catch (IllegalAccessException e) {
                                                e.printStackTrace();
                                            } catch (InvocationTargetException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public void notifyFragmentOnResume() {
        for (Object item : CtrWatcher2.get().getVisibleFragmentController()) {
            if (item instanceof BaseController) {
                ((BaseController) item).onResume();
            }
        }
    }

    public Object findController(Class<?> attach) {
        if (attach != null && getAllVisibleController() != null) {
            for (Object Object : getAllVisibleController()) {
                if (Object.getClass() == attach) {
                    return Object;
                }
            }
        }
        return null;
    }
}
